package cipher.module;

import java.io.IOException;
import java.nio.ByteBuffer;

import cipher.algorithm.Algorithm;

public class Cipher_ {
	
	public static final int ECB = 0;
	public static final int CTR = 1;
	
	public Cipher_() {}
	
	public byte[] chiffrement_(Algorithm a, byte[] in, int MODE, String... arg) throws IOException {
		if(MODE == 0)
			return chiffrement_ecb(a, in);
		else
			return chiffrement_ctr(a, in);
	}
	
	public static byte[] chiffrement(Algorithm a, byte[] in, int MODE, String... arg) throws IOException {
		if(MODE == 0)
			return chiffrement_ecb(a, in);
		else
			return chiffrement_ctr(a, in);
	}

	public byte[] chiffrement_ecb_(Algorithm a, byte[] in) throws IOException {
		byte[] out = new byte[in.length];
		
		for(int i=in.length-1;i>=0;i--)
			// xor l'entrée et le nombre généré
			out[i] = (byte) (in[i] ^ a.generateNextNumber(8));
		
		return out;
	}
	
	public static byte[] chiffrement_ecb(Algorithm a, byte[] in) throws IOException {
		byte[] out = new byte[in.length];
		
		for(int i=in.length-1;i>=0;i--)
			// xor l'entrée et le nombre généré
			out[i] = (byte) (in[i] ^ a.generateNextNumber(8));
		
		return out;
	}
	
	public byte[] chiffrement_ctr_(Algorithm a, byte[] in) throws IOException {
		int i, j, k;
		int rand = 0;
		long seed = 12345678;
		long cpt = 0;
		long tmp = 0;
		
		byte[] out = new byte[in.length];
		byte[] buf = new byte[8];

		seed = seed << 32;
		
		// on traite 64 bits, soit 8 bytes
		for(i=in.length-1;i>=0;i-=8) {
			// générer 64 bits aléatoires
			rand = a.generateNextNumber(64);
			
			// xor le compteur et le nombre généré
			//System.out.println(Long.toBinaryString(seed+cpt));
			tmp = ((seed+cpt)^rand);
			
			// xor l'entrée et le résultat
			buf = ByteBuffer.allocate(8).putLong(tmp).array();
			for(j=8;--j>=0;) {
				k = i-j;
				out[k] = (byte) (in[k]^buf[j]);
			}
			
			cpt++;
		}
		
		return out;
	}
	
	public static byte[] chiffrement_ctr(Algorithm a, byte[] in) throws IOException {
		int i, j, k;
		int rand = 0;
		long seed = 12345678;
		long cpt = 0;
		long tmp = 0;
		
		byte[] out = new byte[in.length];
		byte[] buf = new byte[8];

		seed = seed << 32;
		
		// on traite 64 bits, soit 8 bytes
		for(i=in.length-1;i>=0;i-=8) {
			// générer 64 bits aléatoires
			rand = a.generateNextNumber(64);
			
			// xor le compteur et le nombre généré
			//System.out.println(Long.toBinaryString(seed+cpt));
			tmp = ((seed+cpt)^rand);
			
			// xor l'entrée et le résultat
			buf = ByteBuffer.allocate(8).putLong(tmp).array();
			for(j=8;--j>=0;) {
				k = i-j;
				out[k] = (byte) (in[k]^buf[j]);
			}
			
			cpt++;
		}
		
		return out;
	}
	
}
